package controller

import (
	"encoding/json"
	"io/fs"
	othersmodel "iptv_server/v3/src/models/others_model"
	"iptv_server/v3/src/settings"
	"iptv_server/v3/src/utils"
	vodpush "iptv_server/v3/v2_src/vod_push"
	"os"
	"path"
	"sort"
	"strings"

	"github.com/gin-gonic/gin"
)

type Bili struct {
}

func initOthers(r *gin.Engine) {

	// /tv_others/category/bili/1/1
	r.GET(settings.UrlPath_TvOthers+"/category/:subcate/:folderid/:page", handleOthersCategory)
	r.GET(settings.UrlPath_TvOthers+"/detail/:folderid/:id", handleOthersDetail)
	r.GET(settings.UrlPath_TvOthers+"/play/*id", handleOthersPlay) // 这个 实际没用到

	// /tv_others/category/bili/2/1

}

func handleOthersCategory(ctx *gin.Context) {
	// fmt.Printf("pageX::ctx.Request.RemoteAddr: %v\n", ctx.Request.RemoteAddr)

	reqUrl := ctx.Request.URL.String()
	if strings.HasPrefix(reqUrl, settings.URL_PUSHED_VODID_PREFIX) {
		// 实时 获取!! 这个是 push的!!!
	} else {
		if v, _, ok := cache30min.Get(reqUrl); ok {
			// io.WriteString(ctx.Writer, v)
			ctx.String(200, v)
			return
		}
	}

	//sub cate
	subcate := ctx.Param("subcate")
	folderid := ctx.Param("folderid")
	if len(subcate) == 0 || len(folderid) == 0 {
		ctx.JSON(200, NotFoundJson)
		return
	}

	dir := path.Join(settings.Dir_StaticFile, settings.Dir_Videos, settings.Dir_others_store, subcate, folderid)
	if !utils.IsDir(dir) {
		ctx.JSON(200, NotFoundJson)
		return
	}

	show_all := true
	// fmt.Printf("subcate: %v\n", subcate)
	if subcate == "push" || subcate == "pushed" {
		// ctx.Param 这个是 path中的
		// 这里是 form中的参数!!
		ctx.Request.ParseForm()
		show_all = ctx.Request.Form.Has("showall") // show all
	}

	dsfs0 := utils.ListDir(true, dir)

	type Info struct {
		fs.FileInfo
		show bool
	}
	fileInfos := make([]Info, 0)

	showedFiles := make(map[string]bool)
	f_suffix := vodpush.GetShowSuffix()
	show := func(f string) bool {
		_, ok := showedFiles[f]
		return ok
	}

	var dsfs []fs.DirEntry
	dsfs = make([]fs.DirEntry, 0)
	for _, f := range dsfs0 {
		if !f.Type().IsRegular() {
			continue
		}
		if strings.HasSuffix(f.Name(), ".json") {
			dsfs = append(dsfs, f)
		} else if before, found := strings.CutSuffix(f.Name(), f_suffix); found {
			showedFiles[before+".json"] = true
		}
	}

	for _, f := range dsfs {
		if !f.Type().IsRegular() {
			continue
		}
		if strings.HasSuffix(f.Name(), ".json") {
			finfo, err := f.Info()
			if err == nil {
				// info.ModTime()
				// info.Name()
				// isShow:=show(f.Name())
				info := Info{
					FileInfo: finfo,
					show:     show(f.Name()),
				}
				if show_all {
					fileInfos = append(fileInfos, info)
				} else if info.show {
					fileInfos = append(fileInfos, info)
				}
			}
		}
	}

	// 按创建时间 排序!
	sort.Slice(fileInfos, func(i, j int) bool {
		// return fileInfos[i].ModTime().Before(fileInfos[j].ModTime())// 早的排前面
		return fileInfos[i].ModTime().After(fileInfos[j].ModTime())
	})

	page := ctx.Param("page")

	pg := utils.ParseInter(page, 1)
	pg = max(pg, 1) // 从1开始

	limit := 20
	start := (pg - 1) * limit
	end := start + limit
	end = min(end, len(fileInfos))
	if start >= len(fileInfos) {
		ctx.JSON(200, NotFoundJson)
		return
	}

	fileInfosPaged := fileInfos[start:end]
	pageX := othersmodel.OPage{
		List: make([]*othersmodel.ODetail, 0),
	}

	for _, info := range fileInfosPaged {
		bs, err := os.ReadFile(path.Join(dir, info.Name()))
		if err != nil {
			continue
		}
		detail := new(othersmodel.ODetail)
		err = json.Unmarshal(bs, detail)
		if err != nil {
			continue
		}
		detail.Mode_time = info.ModTime().Unix()
		detail.Show = info.show // HomeActivity,Home2Activity 中区分显示.

		pageX.List = append(pageX.List, detail)
	}
	if len(pageX.List) == 0 {
		ctx.JSON(200, NotFoundJson)
		return
	}

	pageX.Limit = limit
	pageX.Page = pg // page 从1开始
	pageX.PageCount = len(fileInfos) / limit
	if len(fileInfos)%limit != 0 {
		pageX.PageCount += 1
	}

	{
		bs, err := json.Marshal(pageX)
		if err == nil {
			cache30min.Save(reqUrl, string(bs))
			ctx.String(200, string(bs))
		}
	}

	// // // 通过 foldername 获取 folderid

	// folderid, err := strconv.ParseUint(ctx.Param("folderid"), 10, 0)

	// if err != nil || folderid == 0 {
	// 	ctx.JSON(200, NotFoundJson)
	// 	return
	// }
	// // id := ctx.Param("id")
	// // if len(id) == 0 {
	// // 	ctx.JSON(200, NotFoundJson)
	// // 	return
	// // }
	// page := ctx.Param("page")

	// pg := utils.ParseInter(page, 0)
	// pg = max(pg, 0)

	// if ret, err := othersmodel.GetPage(uint(folderid), pg); err != nil {
	// 	ctx.JSON(200, NotFoundJson)
	// } else {
	// 	ctx.JSON(200, ret)
	// }

}

func handleOthersDetail(ctx *gin.Context) {
	// 直接 请求 文件了. 这里都不需要了!!

	// fmt.Printf("handleOthersDetail::ctx.Request.RemoteAddr: %v\n", ctx.Request.RemoteAddr)

	// folderid, err := strconv.ParseUint(ctx.Param("folderid"), 10, 0)

	// fmt.Printf("folderid: %v\n", folderid)
	// if err != nil || folderid == 0 {
	// 	ctx.JSON(200, NotFoundJson)
	// 	return
	// }

	// id, err := strconv.ParseUint(ctx.Param("id"), 10, 0)
	// fmt.Printf("id: %v\n", id)
	// if err != nil || id == 0 {
	// 	ctx.JSON(200, NotFoundJson)
	// 	return
	// }

	// if ret, err := othersmodel.GetDetail(uint(folderid), uint(id)); err != nil {
	// 	ctx.JSON(200, NotFoundJson)
	// } else {
	// 	fmt.Printf("ret: %v\n", ret)
	// 	ctx.JSON(200, ret)
	// }
}

func handleOthersPlay(ctx *gin.Context) {
	// fmt.Printf("ctx.Request.RemoteAddr: %v\n", ctx.Request.RemoteAddr)

	id := ctx.Param("id")
	if len(id) == 0 {
		ctx.JSON(200, NotFoundJson)
		return
	}
	// fmt.Printf("id: %v\n", id)

	if ret, err := othersmodel.GetPlay(id); err != nil {
		ctx.JSON(200, NotFoundJson)
	} else {
		ctx.JSON(200, ret)
	}
}
